import { Request, Response } from 'express';
import { asyncHandler } from '../utils/asyncHandler';
import { AppError } from '../utils/errors';
import { successResponse } from '../utils/response';
import logger from '../utils/logger';
import path from 'path';
import fs from 'fs';

/**
 * @swagger
 * components:
 *   schemas:
 *     UploadResponse:
 *       type: object
 *       properties:
 *         url:
 *           type: string
 *           description: 上传文件的访问URL
 *         filename:
 *           type: string
 *           description: 文件名
 *         originalname:
 *           type: string
 *           description: 原始文件名
 *         size:
 *           type: integer
 *           description: 文件大小（字节）
 *         mimetype:
 *           type: string
 *           description: 文件MIME类型
 *     MultipleUploadResponse:
 *       type: object
 *       properties:
 *         files:
 *           type: array
 *           items:
 *             $ref: '#/components/schemas/UploadResponse'
 *         count:
 *           type: integer
 *           description: 上传文件数量
 */

export class UploadController {
  /**
   * @swagger
   * /api/upload/image:
   *   post:
   *     summary: 上传单张图片
   *     tags: [Upload]
   *     security:
   *       - bearerAuth: []
   *     requestBody:
   *       required: true
   *       content:
   *         multipart/form-data:
   *           schema:
   *             type: object
   *             properties:
   *               image:
   *                 type: string
   *                 format: binary
   *                 description: 图片文件
   *     responses:
   *       200:
   *         description: 图片上传成功
   *         content:
   *           application/json:
   *             schema:
   *               type: object
   *               properties:
   *                 success:
   *                   type: boolean
   *                 message:
   *                   type: string
   *                 data:
   *                   $ref: '#/components/schemas/UploadResponse'
   *       400:
   *         description: 请求参数错误
   *       401:
   *         description: 未授权
   *       413:
   *         description: 文件过大
   */
  uploadSingleImage = asyncHandler(async (req: Request, res: Response) => {
    if (!req.file) {
      throw new AppError('请选择要上传的图片文件', 400);
    }

    const file = req.file;
    // 构建完整的URL
    const protocol = req.protocol;
    const host = req.get('host');
    const fileUrl = `${protocol}://${host}/uploads/images/${file.filename}`;

    logger.info(`图片上传成功: ${file.filename}`, {
      originalname: file.originalname,
      size: file.size,
      mimetype: file.mimetype
    });

    return successResponse(res, {
      url: fileUrl,
      filename: file.filename,
      originalname: file.originalname,
      size: file.size,
      mimetype: file.mimetype
    }, '图片上传成功');
  });

  /**
   * @swagger
   * /api/upload/images:
   *   post:
   *     summary: 上传多张图片
   *     tags: [Upload]
   *     security:
   *       - bearerAuth: []
   *     requestBody:
   *       required: true
   *       content:
   *         multipart/form-data:
   *           schema:
   *             type: object
   *             properties:
   *               images:
   *                 type: array
   *                 items:
   *                   type: string
   *                   format: binary
   *                 description: 图片文件数组（最多10个）
   *     responses:
   *       200:
   *         description: 图片上传成功
   *         content:
   *           application/json:
   *             schema:
   *               type: object
   *               properties:
   *                 success:
   *                   type: boolean
   *                 message:
   *                   type: string
   *                 data:
   *                   $ref: '#/components/schemas/MultipleUploadResponse'
   *       400:
   *         description: 请求参数错误
   *       401:
   *         description: 未授权
   *       413:
   *         description: 文件过大
   */
  uploadMultipleImages = asyncHandler(async (req: Request, res: Response) => {
    const files = req.files as Express.Multer.File[];
    
    if (!files || files.length === 0) {
      throw new AppError('请选择要上传的图片文件', 400);
    }

    // 构建完整的URL
    const protocol = req.protocol;
    const host = req.get('host');

    const uploadedFiles = files.map(file => {
      const fileUrl = `${protocol}://${host}/uploads/images/${file.filename}`;
      
      logger.info(`图片上传成功: ${file.filename}`, {
        originalname: file.originalname,
        size: file.size,
        mimetype: file.mimetype
      });

      return {
        url: fileUrl,
        filename: file.filename,
        originalname: file.originalname,
        size: file.size,
        mimetype: file.mimetype
      };
    });

    return successResponse(res, {
      files: uploadedFiles,
      count: uploadedFiles.length
    }, `成功上传 ${uploadedFiles.length} 张图片`);
  });

  /**
   * @swagger
   * /api/upload/video:
   *   post:
   *     summary: 上传视频文件
   *     tags: [Upload]
   *     security:
   *       - bearerAuth: []
   *     requestBody:
   *       required: true
   *       content:
   *         multipart/form-data:
   *           schema:
   *             type: object
   *             properties:
   *               video:
   *                 type: string
   *                 format: binary
   *                 description: 视频文件
   *     responses:
   *       200:
   *         description: 视频上传成功
   *         content:
   *           application/json:
   *             schema:
   *               type: object
   *               properties:
   *                 success:
   *                   type: boolean
   *                 message:
   *                   type: string
   *                 data:
   *                   $ref: '#/components/schemas/UploadResponse'
   *       400:
   *         description: 请求参数错误
   *       401:
   *         description: 未授权
   *       413:
   *         description: 文件过大
   */
  uploadVideo = asyncHandler(async (req: Request, res: Response) => {
    if (!req.file) {
      throw new AppError('请选择要上传的视频文件', 400);
    }

    const file = req.file;
    // 构建完整的URL
    const protocol = req.protocol;
    const host = req.get('host');
    const fileUrl = `${protocol}://${host}/uploads/videos/${file.filename}`;

    logger.info(`视频上传成功: ${file.filename}`, {
      originalname: file.originalname,
      size: file.size,
      mimetype: file.mimetype
    });

    return successResponse(res, {
      url: fileUrl,
      filename: file.filename,
      originalname: file.originalname,
      size: file.size,
      mimetype: file.mimetype
    }, '视频上传成功');
  });

  /**
   * @swagger
   * /api/upload/delete:
   *   delete:
   *     summary: 删除上传的文件
   *     tags: [Upload]
   *     security:
   *       - bearerAuth: []
   *     requestBody:
   *       required: true
   *       content:
   *         application/json:
   *           schema:
   *             type: object
   *             properties:
   *               filename:
   *                 type: string
   *                 description: 要删除的文件名
   *             required:
   *               - filename
   *     responses:
   *       200:
   *         description: 文件删除成功
   *       400:
   *         description: 请求参数错误
   *       401:
   *         description: 未授权
   *       404:
   *         description: 文件不存在
   */
  deleteFile = asyncHandler(async (req: Request, res: Response) => {
    const { filename } = req.body;

    if (!filename) {
      throw new AppError('请提供要删除的文件名', 400);
    }

    // 安全检查：确保文件名不包含路径遍历字符
    if (filename.includes('..') || filename.includes('/') || filename.includes('\\')) {
      throw new AppError('无效的文件名', 400);
    }

    const filePath = path.join(__dirname, '../../uploads/images', filename);

    // 检查文件是否存在
    if (!fs.existsSync(filePath)) {
      throw new AppError('文件不存在', 404);
    }

    try {
      // 删除文件
      fs.unlinkSync(filePath);
      
      logger.info(`文件删除成功: ${filename}`);
      
      return successResponse(res, null, '文件删除成功');
    } catch (error) {
      logger.error(`文件删除失败: ${filename}`, error);
      throw new AppError('文件删除失败', 500);
    }
  });

  /**
   * @swagger
   * /api/upload/info:
   *   get:
   *     summary: 获取上传配置信息
   *     tags: [Upload]
   *     responses:
   *       200:
   *         description: 获取配置信息成功
   *         content:
   *           application/json:
   *             schema:
   *               type: object
   *               properties:
   *                 success:
   *                   type: boolean
   *                 data:
   *                   type: object
   *                   properties:
   *                     maxFileSize:
   *                       type: integer
   *                       description: 最大文件大小（字节）
   *                     maxFiles:
   *                       type: integer
   *                       description: 最大文件数量
   *                     allowedTypes:
   *                       type: array
   *                       items:
   *                         type: string
   *                       description: 允许的文件类型
   */
  getUploadInfo = asyncHandler(async (req: Request, res: Response) => {
    const uploadInfo = {
      maxFileSize: 10 * 1024 * 1024, // 10MB
      maxFiles: 10,
      allowedTypes: ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'],
      allowedExtensions: ['.jpg', '.jpeg', '.png', '.gif', '.webp']
    };

    return successResponse(res, uploadInfo, '获取上传配置信息成功');
  });
}